package com.h3bpm.web.common.utils;

import OThinker.Common.DateTimeUtil;
import data.DataTable;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author zhengyj
 * @date 2019/6/24
 * @description 将dataTable转为VO对象
 */
public class DataTableToVoListUtil<T> {


    public  List<T> dataTableToVOList(Class<T> clazz, DataTable dt) {
        Field field = null;
        List<T> lists = new ArrayList<T>();

        try {
            if (dt.getRows().size() > 0) {
                int counts = dt.getColumns().size();
                // 定义counts个String 变量
                String[] columnNames = new String[counts];
                // 给每个变量赋值
                for (int i = 0; i < counts; i++) {
                    columnNames[i] = dt.getColumns().get(i).getColumnName();
                }

                for (Field field1 : clazz.getDeclaredFields()) {
                    for (int i = 0; i < columnNames.length; i++) {
                        if (field1.getName().toUpperCase().equals(columnNames[i])) {
                            columnNames[i] = field1.getName();
                        }
                    }

                }
                // 行值
                for(int i = 0; i < dt.getRows().size(); i++) {
                    // 根据 dt 列名 ，组装javaBean里边的其中一个set方法，object 就是数据库第一行第一列的数据了
                    T t = clazz.newInstance();
                    // 反射, 从ResultSet绑定到JavaBean				e:
                    for (int j = 0; j < counts; j++) {
                        // 根据 rs 列名 ，组装javaBean里边的其中一个set方法，object 就是数据库第一行第一列的数据了
                        Object value = null;
                        Class<?> dbType = null;
                        //try的意义是在于 获取对象为空时
                        try {
                            value = dt.getRows().get(i).getObject(columnNames[j]);
                            //这里是获取数据库字段的类型   判断 value是否为空 null的话跳过
                            dbType = value.getClass();
                        } catch (Exception e) {
                            continue;
                        }
                        //设置参数类型，此类型应该跟javaBean 里边的类型一样，而不是取数据库里边的类型
                        field = clazz.getDeclaredField(columnNames[j]);
                        Class<?> beanType = field.getType();
                        //如果发生从数据库获取到得类型跟javaBean类型不同，按String类型取吧//
                        if (beanType != dbType) {
                            value = dt.getRows().get(i).getString(columnNames[j]);
                        }
                        if (beanType == Date.class) {
                            value = DateTimeUtil.getStringToDate((String) value, null);
                        }

                        if (beanType == int.class) {
                            value = dt.getRows().get(i).getInt(columnNames[j]);
                        }

                        String setMethodName = "set" + firstUpperCase(columnNames[j]);
                        // 第一个参数是传进去的方法名称，第二个参数是 传进去的类型；
                        Method m = t.getClass().getMethod(setMethodName, beanType);
                        // 第二个参数是传给set方法数据；如果是get方法可以不写
                        m.invoke(t, value);
                    }
                    lists.add(t);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }


        return lists;
    }

    /**
     * 首写字母变大写
     * @param old
     * @return
     */
    public static String firstUpperCase(String old) {
        return old.substring(0, 1).toUpperCase() + old.substring(1);
    }

}
